package com.iteaj.iot.server.component;

import com.iteaj.iot.config.ConnectProperties;
import com.iteaj.iot.server.ServerMessage;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.FixedLengthFrameDecoder;

/**
 * 固定长度解码器组件
 * @param <M>
 */
public abstract class FixedLengthFrameDecoderComponent<M extends ServerMessage> extends SocketDecoderComponent<M> {

    private int frameLength;

    public FixedLengthFrameDecoderComponent(ConnectProperties connectProperties, int frameLength) {
        super(connectProperties);
        this.frameLength = frameLength;
    }

    @Override
    public ChannelInboundHandlerAdapter getMessageDecoder() {
        return new FixedLengthFrameDecoderAdapter(this.frameLength);
    }

    protected class FixedLengthFrameDecoderAdapter extends FixedLengthFrameDecoder {

        /**
         * Creates a new instance.
         *
         * @param frameLength the length of the frame
         */
        public FixedLengthFrameDecoderAdapter(int frameLength) {
            super(frameLength);
        }

        @Override
        protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
            Object decode = super.decode(ctx, in);
            if(decode instanceof ByteBuf) {
                try {
                    M message = FixedLengthFrameDecoderComponent.this.proxy(ctx, (ByteBuf) decode);

                    return message != null ? message : decode;
                } finally {
                    ((ByteBuf) decode).release();
                }
            }

            return decode;
        }
    }
}
